ftofficer |
您所在的位置:网站首页 › 深圳大学 语言学 › ftofficer |
æœ€è¿‘æœ‰ä¸€ä¸ªéœ€æ±‚ï¼Œç»™ä½ ä¸ªåœ°å€ï¼Œçœ‹çœ‹è¿™ä¸ªåœ°å€å‰é¢æ˜¯ä¸æ˜¯ä¸€ä¸ªCALL指令(请åŒå¦ä»¬è‡ªè¡Œè”想该需求的æ¥æºï¼‰ã€‚作为团队的救ç«é˜Ÿå‘˜+ç‚®ç°ï¼Œè¿™ä¸ªç®€å•çš„事情自然è½åœ¨äº†æˆ‘的头上。 这个事情很简å•ï¼Œä½œä¸ºä¸€ä¸ªå–„于站在别人肩膀上的程åºå‘˜æˆ‘们å¯ä»¥è€ƒè™‘使用 libdisasm;如果è¦è€ƒè™‘x64,就试试udis86;如果需è¦ç”¨Python,就有Python包装好的 pydasm。ä¸è¿‡è¿™ä¸¤ä¸ª400KB+的库,显然ä¸å€¼å¾—为了一个CALL指令导入到编译出æ¥å¤§å°ä»…ä»…100Kä¸åˆ°çš„项目代ç 里é¢ã€‚ 那么就自己抽一个CALL指令解ç 逻辑出æ¥å¥½äº†ã€‚这个逻辑的å¤æ‚æ€§åœ¨äºŽï¼Œä½ æ— æ³•çŸ¥é“å‰é¢ä¸€ä¸ªCALLæŒ‡ä»¤æœ‰å¤šé•¿ã€‚å› æ¤ï¼Œé¦–先需è¦æžšä¸¾å‡ºæ‰€æœ‰çš„CALLæŒ‡ä»¤æ ¼å¼ã€‚ Intelæœ‰å…¬å¼€çš„æŒ‡ä»¤é›†æ ¼å¼æ–‡æ¡£ï¼Œä½ 需è¦çš„是第二å·çš„上åŠéƒ¨åˆ†ï¼ŒæŒ‡ä»¤é›†ä»ŽA到M。这篇文档的难度超出一般人想象,里é¢æœ‰ä¼—å¤šæ™¦æ¶©çš„æ ‡è¯†ã€ä¸Žç¡¬ä»¶ç´§å¯†ç›¸å…³çš„介ç»ï¼Œæ‹¿åˆ°è¿™åŽï¼Œå³ä½¿ç›´æŽ¥ç¿»åˆ°ç›®å½•çš„CALL 指令一节,也ä¸è§å¾—能够弄清楚。ä¸ç›¸ä¿¡ï¼Ÿæˆ‘们就翻到那里看看: 虽然很明确的列出,第一列是指令的二进制形å¼ï¼Œç¬¬äºŒåˆ—是指令的汇编形å¼ï¼Œä½†æ˜¯é¢å¯¹ç€ E8 cw, FF/2è¿™æ ·çš„æ ‡è¯†ï¼Œä¸€æ ·ä¸çŸ¥é“ç©¶ç«Ÿå¯¹åº”çš„äºŒè¿›åˆ¶æ ¼å¼æ˜¯ä»€ä¹ˆæ ·çš„。 那好,我们就从ç†è§£è¿™äº›æ ‡è¯†å¼€å§‹ã€‚文档å‘å‰ç¿»ï¼Œæœ‰ä¸€ä¸ªä¸“门的节(3.1.1 Instruction Formatï¼‰è®²è¿°è¿™äº›æ ‡è¯†çš„å«ä¹‰ã€‚这里抽出其ä¸ä¸¤ä¸ªç”¨å¾—ç€çš„翻译一下: è¡¨æ ¼ä¸çš„“Opcodeâ€åˆ—列出了所有的所有å¯èƒ½çš„æŒ‡ä»¤å¯¹åº”çš„äºŒè¿›åˆ¶æ ¼å¼ã€‚有å¯èƒ½çš„è¯ï¼ŒæŒ‡ä»¤ä»£ç 使用åå…进制显示它们在内å˜å½“ä¸çš„å—节。除了这些16进制代ç 之外的部分使用下é¢çš„æ ‡è®°ï¼š cb, cw, cd, cp, co, ct — opcodeåŽé¢è·Ÿç€çš„一个1å—节(cb),2å—节(cw),4å—节(cd),6å—节 (cp),8å—节(co) 或者 10å—节(ct) 的值。这个值用æ¥è¡¨ç¤ºä»£ç å移地å€ï¼Œæœ‰å¯èƒ½çš„è¯è¿˜åŒ…括代ç 段寄å˜å™¨çš„值。 /digit — digit为0到7之间的数å—,表示指令的 ModR/M byte åªä½¿ç”¨ r/må—段作为æ“作数,而其regå—段作为opcode的一部分,使用digit指定的数å—。 红å—部分ä¸çŸ¥é“什么å«ä¹‰ï¼Ÿæ²¡å…³ç³»ï¼Œæˆ‘们先ä¸çœ‹å®ƒã€‚对于cb/cw之类的,基本上能够简å•çœ‹æ˜Žç™½å…¶ä¸çš„一些指令å«ä¹‰äº†ï¼š E8 cw çš„å«ä¹‰æ˜¯ï¼šå—节 0xE8 åŽé¢è·Ÿç€ä¸€ä¸ª2å—节æ“作数表示è¦è·³è½¬åˆ°çš„地å€ä¸Žå½“å‰åœ°å€çš„å移é‡ã€‚ E8 cd çš„å«ä¹‰æ˜¯ï¼šå—节 0xE8 åŽé¢è·Ÿç€ä¸€ä¸ª4å—节的æ“作数表示è¦è·³è½¬çš„地å€ä¸Žå½“å‰åœ°å€çš„å移é‡ã€‚ 9A cd çš„å«ä¹‰æ˜¯ï¼šå—节 0x9A åŽé¢è·Ÿç€ä¸€ä¸ª6å—节的æ“作数表示è¦è·³è½¬çš„地å€å’Œä»£ç 段寄å˜å™¨çš„值。 那么,åŒæ ·çš„0xE8开头的指令,CPU如何区分åŽé¢çš„æ“作数是2å—节还是4å—节?ç”案是和CPU的模å¼æœ‰å…³ï¼Œåœ¨å®žæ¨¡å¼ä¸‹ï¼Œ0xE8接å—2å—节æ“作数,而32ä½ä¿æŠ¤æ¨¡å¼ä¸‹æŽ¥å—4个å—节,64ä½ä¿æŠ¤æ¨¡å¼ä¸‹åŒæ ·æŽ¥å—4å—节,åŒæ—¶éœ€è¦å¯¹è¯¥æ“作数进行带符å·æ‰©å±•ã€‚ å› æ¤ï¼ŒCALL指令的å‰ä¸¤ç§æ ¼å¼æ˜¯ï¼šE8 xx xx xx xx,和 9A xx xx xx xx xx xx。一个是5å—节长,一个是7å—节长。其实E8 é‚£ç§ï¼Œå°±æ˜¯æˆ‘们在汇编指令里é¢å†™ CALL lable之åŽäº§ç”Ÿçš„,最常è§çš„CALL指令。 然åŽæ˜¯ä¸‹é¢çš„FF /2。这个是0xFFå—节åŽé¢è·Ÿä¸Šä¸€ä¸ªblablabla的东西。这个blablabla的东西是什么呢?è¦è§£é‡Šè¿™ä¸ªï¼Œé¦–先需è¦çŸ¥é“红å—æ ‡å‡ºæ¥çš„部分,å³ModR/M是什么东西。 这个è¦å…ˆå›žåˆ°æœ€åŸºæœ¬çš„一个问题:IA32çš„æŒ‡ä»¤æ ¼å¼ã€‚ å…¶ä¸æ¯ä¸ªéƒ¨åˆ†æ˜¯ä»€ä¹ˆå«ä¹‰å‘¢ï¼Ÿ 首先是指令å‰ç¼€ã€‚有å°è±¡çš„应该记得当年å¦ä¹ 微机原ç†çš„时候æ到过得循环å‰ç¼€ repnz/repne,这个å‰ç¼€å°±æ˜¯è¢«ç¼–ç 在指令的å‰é¢éƒ¨åˆ†çš„。æ¯ä¸ªå‰ç¼€æœ€å¤šä¸€ä¸ªå—节,一æ¡æŒ‡ä»¤æœ€å¤š4个å‰ç¼€ã€‚ 然åŽæ˜¯æŒ‡ä»¤ä»£ç (opcodeï¼‰ï¼Œè¿™éƒ¨åˆ†æ ‡è¯†äº†æŒ‡ä»¤æ˜¯ä»€ä¹ˆã€‚è¿™ä¸ªæ˜¯æŒ‡ä»¤å½“ä¸å”¯ä¸€å¿…需的部分。å‰é¢ä¾‹å当ä¸çš„ 0xE8,0xFF都是opcode。 å†åŽé¢å°±æ˜¯æˆ‘们è¦é‡ç‚¹å…³å¿ƒçš„ ModR/Må—段了,还有和它密切相关的SIBå—节。手册2.1.3当ä¸æœ‰å¯¹äºŽå®ƒä»¬çš„详细æ述。 许多指令需è¦å¼•ç”¨åˆ°ä¸€ä¸ªåœ¨å†…å˜å½“ä¸çš„值作为æ“作数,这ç§æŒ‡ä»¤éœ€è¦ä¸€ä¸ªç§°ä¸ºå¯»å€æ¨¡å¼æ ‡è¯†å—节(addressing-form specifier byte),或者å«åšModR/Må—节紧跟在主opcodeåŽé¢ã€‚ModR/Må—节包å«ä¸‹é¢ä¸‰ä¸ªéƒ¨åˆ†çš„ä¿¡æ¯ï¼š mod(模å¼ï¼‰åŸŸï¼Œè¿žåŒr/m(寄å˜å™¨/内å˜ï¼‰åŸŸå…±åŒæž„æˆäº†32个å¯èƒ½çš„值:8个寄å˜å™¨å’Œ24个寻å€æ¨¡å¼ã€‚ reg/opcode(寄å˜å™¨/æ“作数)域指定了8个寄å˜å™¨æˆ–者é¢å¤–çš„3个å—节的opcode。究竟这三个å—节用æ¥åšä»€ä¹ˆç”±ä¸»opcode指定。 r/m(寄å˜å™¨/内å˜ï¼‰åŸŸå¯ä»¥æŒ‡å®šä¸€ä¸ªå¯„å˜å™¨ä½œä¸ºæ“作数,或者å¯ä»¥å’Œmod域è”åˆç”¨æ¥æŒ‡å®šå¯»å€æ¨¡å¼ã€‚有时候,它和mod域一起用æ¥ä¸ºæŸäº›æŒ‡ä»¤æŒ‡å®šé¢å¤–çš„ä¿¡æ¯ã€‚这一段有些晦涩。其æ„æ€è§£é‡Šä¸€ä¸‹æ˜¯è¿™æ ·çš„:一个指令往往需è¦å¼•ç”¨ä¸€ä¸ªåœ¨å†…å˜å½“ä¸çš„值,典型的就是如mov: MOV eax, dword ptr [123456] MOV eax, dword ptr [esi] 这其ä¸çš„ 123456 或者 esi 就是 MOV 指令引用的内å˜åœ°å€ï¼Œè€ŒMOV关心的是这个地å€å½“ä¸çš„内容。这个时候,需è¦æŸç§æ–¹å¼æ¥ä¸ºæŒ‡ä»¤æŒ‡å®šè¿™ä¸ªæ“作数的类型:是一个立å³æ•°è¡¨ç¤ºçš„地å€ï¼Œè¿˜æ˜¯ä¸€ä¸ªå˜æ”¾åœ¨å¯„å˜å™¨å½“ä¸çš„地å€ï¼Œæˆ–者,就是寄å˜å™¨æœ¬èº«ã€‚ 这个用æ¥åŒºåˆ†æ“作数类型的指令å—节就是 ModR/M,确切的说是其ä¸çš„5个ä½ï¼Œå³modå’Œr/m域。剩下的三个ä½ï¼Œå¯èƒ½ç”¨æ¥åšé¢å¤–的指令å—èŠ‚ã€‚å› ä¸ºï¼ŒIA32的指令个数已ç»è¿œè¶…过一个å—节所能表示的256ä¸ªäº†ã€‚å› æ¤ï¼Œæœ‰çš„指令就è¦å¤ç”¨ç¬¬ä¸€ä¸ªå—节,然åŽä¾æ®ModR/M当ä¸çš„reg/opcode域进行区分。 现在回头看å‰é¢çš„红å—æ ‡è¯†çš„éƒ¨åˆ†ï¼Œèƒ½ä¸èƒ½ç†è§£ /digit è¿™ç§è¡¨ç¤ºæ³•äº†ï¼Ÿ 对于SIB的介ç»ï¼Œæˆ‘们先忽略,看看对于CALL指令的枚举我们已ç»èƒ½åšä»€ä¹ˆäº†ã€‚ CALL指令的表示法:FF /2,是 0xFF åŽé¢è·Ÿç€ä¸€ä¸ª /digit 表示的东西。就是说,0xFFåŽé¢éœ€è¦è·Ÿä¸€ä¸ª ModR/M å—节,ModR/Må—节使用 reg/opcode 域 = 2 。那么,reg/opcode = 2 çš„å—节有32个,æ£å¦‚ModR/M的解释,这32个值代表了32ç§ä¸åŒçš„寻å€æ–¹å¼ã€‚是哪32ç§å‘¢ï¼Ÿæ‰‹å†Œä¸Šé¢æœ‰å¼ 表: éžå¸¸å¤æ‚çš„ä¸€å¼ è¡¨ã€‚çŽ°åœ¨å°±çœ‹çœ‹è¿™å¼ è¡¨æ€Žä¹ˆè¯»ã€‚ 首先是列的定义。由于 reg/opcode 域å¯ä»¥ç”¨æ¥è¡¨ç¤ºopcode,也å¯ä»¥ç”¨æ¥è¡¨ç¤ºregï¼Œå› æ¤åŒä¸€ä¸ªå€¼åœ¨ä¸åŒçš„指令当ä¸å¯èƒ½ä»£è¡¨ä¸åŒçš„å«ä¹‰ã€‚在表当ä¸ï¼Œå°±è¡¨çŽ°ä¸ºæ¯ä¸€åˆ—的表头都有很多个ä¸åŒçš„表示。我们需è¦å…³å¿ƒçš„就是 opcode 这一个。注æ„看我用红圈圈出æ¥çš„部分,这一列就是 opcode=2 的一列。而我们需è¦çš„ CALL 指令,也就是在这一列当ä¸ï¼Œ0xFFåŽé¢éœ€è¦è·Ÿç€çš„内容。 行的定义就是ä¸åŒçš„寻å€æ¨¡å¼ã€‚æ£å¦‚手册所说,mod + R/M域,共5个å—节,定义了32ç§å¯»å€æ¨¡å¼ã€‚0x10 – 0x17 对应于寄å˜å™¨å¯»å€ã€‚例如指令 CALL dword ptr [eax] :[eax]寻å€å¯¹åº”的是 0x10ï¼Œå› æ¤ï¼Œè¯¥æŒ‡ä»¤å¯¹åº”的二进制就是 FF 10。åŒç†ï¼Œ CALL dword ptr [ebx] 是 FF 13,CALL dword ptr [esi] 是 FF 16,这些指令都是2个å—节。有人也许问 CALL word ptr [eax] 是什么?抱æ‰ï¼Œè¿™ä¸æ˜¯ä¸€ä¸ªåˆæ³•çš„32ä½æŒ‡ä»¤ã€‚ 0x50-0x57部分需è¦å¸¦ä¸€ä¸ª disp8ï¼Œå³ 8bit ç«‹å³æ•°ï¼Œä¹Ÿå°±æ˜¯ä¸€ä¸ªå—节。这个是基地å€+8ä½å移é‡çš„寻å€æ¨¡å¼ã€‚例如 CALL dword ptr [eax+10] 就是 FF 50 10 。注æ„虽然表当ä¸å†™çš„是 [eax] + disp8 è¿™ç§å½¢å¼ï¼Œä½†æ˜¯å¹¶ä¸è¡¨ç¤ºæ˜¯å–å¾— eax 指å‘的地å€å½“ä¸çš„值å†åŠ 上 disp8,而是在eaxä¸ŠåŠ ä¸Šdisp8å†è¿›è¡Œå¯»å€ã€‚å› æ¤å†™æˆ [eax+disp8] æ›´ä¸å®¹æ˜“引起误解。åŽé¢çš„disp32ä¹Ÿæ˜¯ä¸€æ ·çš„ã€‚è¿™ä¸ªç±»åž‹æŒ‡ä»¤æ˜¯3个å—节。 0x90 – 0x97部分需è¦å¸¦ disp32,å³4å—节立å³æ•°ã€‚这个是基地å€+32ä½å移é‡ã€‚例如 CALL dword ptr [eax+12345] 就是 FF 90 00 01 23 45。有趣的是, CALL dword ptr [eax+10] 也å¯ä»¥å†™æˆ FF 90 00 00 00 10。至于汇编æˆå“ªä¸ªäºŒè¿›åˆ¶å½¢å¼ï¼Œè¿™æ˜¯æ±‡ç¼–器的选择。这个类型的指令是6个å—节。 0xD0 – 0xD7部分则直接是寄å˜å™¨ã€‚这边引用的寄å˜å™¨çš„类型有很多,但是在CALL指令当ä¸åªèƒ½å¼•ç”¨é€šç”¨å¯„å˜å™¨ï¼Œå› æ¤ CALL eax 就是 FF D0,è‡åæ˜è‘—çš„ CALL esp 就是 FF D4ã€‚æ³¨æ„ CALL eax å’Œ CALL [eax] 是ä¸ä¸€æ ·çš„。这些指令也是2个å—节。 仔细的人也许主è¦åˆ°äº†ï¼Œåœ¨è¡¨å½“ä¸ï¼Œ0x14, 0x15, 0x54å’Œ0x94是ä¸ä¸€æ ·çš„。0x15比较简å•ï¼Œè¿™ä¸ªè¦æ±‚ ModR/MåŽé¢è·Ÿä¸Šä¸€ä¸ª32ä½ç«‹å³æ•°ä½œä¸ºåœ°å€ã€‚å³å¸¸è§çš„ CALL dword ptr [004F778e] è¿™ç§æ ¼å¼çš„,直接跳转到一个固定内å˜åœ°å€å¤„å˜æ”¾çš„值,常è§äºŽè°ƒç”¨Windows的导出表。对应的二进制是 FF 15 00 4F 77 8E ,有6个å—节。 0x14,0x54,0x94部分是最å¤æ‚çš„ï¼Œå› ä¸ºè¿™ä¸ªæ—¶å€™ï¼ŒModR/Mä¸è¶³ä»¥æŒ‡å®šå¯»å€æ–¹å¼ï¼Œè€Œæ˜¯éœ€è¦ä¸€ä¸ªé¢å¤–çš„å—节,这个å—节就是指令当ä¸çš„第4个å—节,SIB。åŒæ ·åœ¨æ‰‹å†Œçš„2.1.3,紧跟ç€ModR/M的定义: æŸäº›ç‰¹å®šçš„ModR/Må—节需è¦ä¸€ä¸ªåŽç»å—节,称为SIBå—节。32ä½æŒ‡ä»¤çš„基地å€+å移é‡ï¼Œä»¥åŠ 比例*åç§»é‡ çš„å½¢å¼çš„寻å€æ–¹å¼éœ€è¦SIBå—节。 SIBå—节包括下列信æ¯ï¼š scale(比例)域指定了放大的比例。 index(å移)域指定了用æ¥å˜æ”¾åç§»é‡ çš„å¯„å˜å™¨ã€‚ base (基地å€ï¼‰åŸŸç”¨æ¥æ ‡è¯†å˜æ”¾åŸºåœ°å€çš„寄å˜å™¨ã€‚0x14, 0x54, 0x94就是这里所说的“特定的ModR/Må—节。这个å—节åŽé¢è·Ÿç€çš„SIB表示了一个å¤æ‚的寻å€æ–¹å¼ï¼Œå…¸åž‹çš„è§äºŽè™šå‡½æ•°è°ƒç”¨ï¼š CALL dword ptr [ecx+4*eax] 就是调用ecx指å‘的虚表当ä¸çš„第eax个虚函数。这个指令当ä¸ï¼Œå› 为没有立å³æ•°ï¼Œå› æ¤FFåŽé¢çš„å—节就是0x14,而 [ecx+4*eax] 就需è¦ç”¨SIBå—节æ¥è¡¨ç¤ºã€‚在这个指令当ä¸ï¼Œecx就是 Base,4是Scale,eax是Index。 那么,Base, Scaleå’ŒIndex是如何确定的呢?手册上åŒæ ·æœ‰ä¸€å¼ 表(åˆæ˜¯å·¨å¤§çš„表): 列是Base,行是Index*Scale,例如[ecx+4*eax] 就是0x81。 æ ¹æ®è¿™å¼ 表,CALL dword ptr [ecx+4*eax] 就是 FF 14 81 。由æ¤å¯è§ï¼Œå¯¹äºŽ 0x14系列的æ¥è¯´ï¼ŒCALL指令就是 3个å—节。 而 0x54 带 8bit ç«‹å³æ•°ï¼Œå°±æ˜¯å¯¹åº”于 CALL指令:CALL dword ptr [ecx+4*eax+xx],这个指令就是 FF 54 81 xx,是4个å—节。 åŒç†ï¼Œ0x94带32ä½ç«‹å³æ•°ï¼Œå¯¹åº”于CALL指令:CALL dword ptr [ecx+4*eax+xxxxxxxx],这个指令就是 FF 94 81 xx xx xx xx,是7个å—节。 OK,截æ¢åˆ°ç›®å‰ï¼Œæˆ‘们基本上能够列出常è§çš„CALLæŒ‡ä»¤çš„æ ¼å¼äº†ï¼š 指令 äºŒè¿›åˆ¶å½¢å¼ CALL rel32 E8 xx xx xx xx CALL dword ptr [EAX] FF 10 CALL dword ptr [ECX] FF 11 CALL dword ptr [EDX] FF 12 CALL dword ptr [EBX] FF 13 CALL dword ptr [REG*SCALE+BASE] FF 14 xx CALL dword ptr [abs32] FF 15 xx xx xx xx CALL dword ptr [ESI] FF 16 CALL dword ptr [EDI] FF 17 CALL dword ptr [EAX+xx] FF 50 xx CALL dword ptr [ECX+xx] FF 51 xx CALL dword ptr [EDX+xx] FF 52 xx CALL dword ptr [EBX+xx] FF 53 xx CALL dword ptr [REG*SCALE+BASE+off8] FF 54 xx xx CALL dword ptr [EBP+xx] FF 55 xx CALL dword ptr [ESI+xx] FF 56 xx CALL dword ptr [EDI+xx] FF 57 xx CALL dword ptr [EAX+xxxxxxxx] FF 90 xx xx xx xx CALL dword ptr [ECX+xxxxxxxx] FF 91 xx xx xx xx CALL dword ptr [EDX+xxxxxxxx] FF 92 xx xx xx xx CALL dword ptr [EBX+xxxxxxxx] FF 93 xx xx xx xx CALL dword ptr [REG*SCALE+BASE+off32] FF 94 xx xx xx xx xx CALL dword ptr [EBP+xxxxxxxx] FF 95 xx xx xx xx CALL dword ptr [ESI+xxxxxxxx] FF 96 xx xx xx xx CALL dword ptr [EDI+xxxxxxxx] FF 97 xx xx xx xx CALL EAX FF D0 CALL ECX FF D1 CALL EDX FF D2 CALL EBX FF D3 CALL ESP FF D4 CALL EBP FF D5 CALL ESI FF D6 CALL EDI FF D7 CALL FAR seg16:abs32 9A xx xx xx xx xx xx有了这个列表,写一段代ç æ¥å®Œæˆæœ€åˆæˆ‘们的需求也就ä¸éš¾äº†ã€‚ |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |